package com.zxq.ruoyi.channel.translator.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zxq.factory.datatrim.CurIndex;
import com.zxq.factory.datatrim.DataTrimFactory;
import com.zxq.factory.datatrim.ITrimInterpreter;
import com.zxq.factory.decoder.FiledDecoderFactory;
import com.zxq.factory.decoder.IFieldDecoder;
import com.zxq.factory.encoder.FiledEncoderFactory;
import com.zxq.factory.encoder.IFieldEncoder;
import com.zxq.factory.enums.EField;
import com.zxq.factory.enums.ETrimMethod;
import com.zxq.factory.utils.BigLittleEndian;
import com.zxq.memory.ByteCombination;
import com.zxq.ruoyi.channel.translator.ITransformCmdService;
import com.zxq.ruoyi.domain.IotCmd;
import com.zxq.ruoyi.domain.IotCmdDecode;
import com.zxq.ruoyi.domain.IotCmdEncoder;
import com.zxq.ruoyi.domain.IotPacketField;
import com.zxq.ruoyi.service.impl.IotCmdDecodeServiceImpl;
import com.zxq.ruoyi.service.impl.IotCmdEncoderServiceImpl;
import com.zxq.ruoyi.service.impl.IotCmdServiceImpl;
import com.zxq.ruoyi.service.impl.IotPacketFieldServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class TransformCmdServiceImpl implements ITransformCmdService {

    /**
     * 设备指令解码
     */
    @Autowired
    IotCmdDecodeServiceImpl iotCmdDecodeDoService;

    /**
     * 平台指令编码
     */
    @Autowired
    IotCmdEncoderServiceImpl iotCmdEncoderDoService;

    /**
     * cmd服务
     */
    @Autowired
    IotCmdServiceImpl cmdDoService;

    /**
     * 寻找包内所有字段
     */
    @Autowired
    IotPacketFieldServiceImpl iotPacketFieldDoService;


    @Override
    public byte[] platformTransform(Long cmdId, JSONObject json) {
        IotCmdEncoder iotCmdEncoderCondition = new IotCmdEncoder();
        iotCmdEncoderCondition.setCmdId(cmdId);
        List<IotCmdEncoder> iotCmdEncoderDos = iotCmdEncoderDoService.selectIotCmdEncoderList(iotCmdEncoderCondition);

        iotCmdEncoderDos.sort((o1,o2) ->{
            return o1.getSequence().intValue() - o2.getSequence().intValue();
        });
        List<byte[]> cmdTotal = new ArrayList<>();
        iotCmdEncoderDos.forEach(item -> {
            byte[] msg = fieldEncoder(item,json);
            cmdTotal.add(msg);
        });
        byte[] total = ByteCombination.combinationContent(cmdTotal);
        return total;
    }


    @Override
    public JSONObject deviceTransform(Long cmdId, byte[] frame) {
        IotCmd iotCmdDo = cmdDoService.selectIotCmdById(cmdId);
        Long cmd_id =  iotCmdDo.getId();
        IotCmdDecode iotCmdDecodeDo = new IotCmdDecode();
        iotCmdDecodeDo.setCmdId(cmd_id);
        List<IotCmdDecode> iotCmdDecodeDos = iotCmdDecodeDoService.selectIotCmdDecodeList( iotCmdDecodeDo);
        iotCmdDecodeDos.sort(((o1, o2) -> {
            return o1.getSequence().intValue() - o2.getSequence().intValue();
        }));

        JSONObject json = new JSONObject();
        CurIndex curIndex = new CurIndex();
        iotCmdDecodeDos.forEach(item ->{
            Object value = fieldDecoder(item,frame,curIndex);
            Long fieldId = item.getFieldId();
            IotPacketField iotPacketFieldDo = iotPacketFieldDoService.selectIotPacketFieldById(fieldId);
            String field = iotPacketFieldDo.getField();
            json.put(field,value);
        });

        return json;
    }

    /**
     * 一个标注，类似于改字段是一个包裹的包
     *     Frame(0),
     *     Int(1),
     *     Bytes(2),
     *     Long(3),
     *     String(4),
     *     Boolean(5),
     *     Float(6),
     *     Double(7),
     *     Hex(8),
     *     Byte(9),
     * frame不支持，因为是帧类型，不太好处理关系
     */
    private byte[] fieldEncoder(IotCmdEncoder item, JSONObject jsonObject) {
        Long fieldId = item.getFieldId();
        IotPacketField iotPacketFieldDo = iotPacketFieldDoService.selectIotPacketFieldById(fieldId);
        if(iotPacketFieldDo == null) {
            log.info("not find field");
        }
        String filed = iotPacketFieldDo.getField();
        Integer fieldType = iotPacketFieldDo.getFieldType().intValue();
        EField eField = EField.getType(fieldType.intValue());
        IFieldEncoder iFieldEncoder = FiledEncoderFactory.instance().create(eField);
        byte[] msg = iFieldEncoder.encoder(jsonObject.get(filed),iotPacketFieldDo.getLen().intValue());
        if(iotPacketFieldDo.getBigLittleEndian() != null && iotPacketFieldDo.getBigLittleEndian().isEmpty()) {
            msg = BigLittleEndian.encoder(iotPacketFieldDo.getBigLittleEndian(), msg);
        }
        return msg;
    }


    /**
     * 字段解码
     * @param item cmd内的一个记录，记录cmd内字段描述
     * @param msg byte数据
     * @param curIndex 索引记录器
     * @return
     */
    private Object fieldDecoder(IotCmdDecode item, byte[] msg, CurIndex curIndex) {
        ETrimMethod eTrimMethod = ETrimMethod.getType(item.getTrimType().intValue());
        ITrimInterpreter iTrimInterpreter = DataTrimFactory.instance().create(eTrimMethod);
        byte[] data = iTrimInterpreter.interpreter(msg,curIndex,item.getTrimParam().intValue());
        Long fieldId =  item.getFieldId();
        IotPacketField iotPacketFieldDo = iotPacketFieldDoService.selectIotPacketFieldById(fieldId);
        EField eField = EField.getType(iotPacketFieldDo.getFieldType().intValue());
        IFieldDecoder iFieldDecoder = FiledDecoderFactory.instance().create(eField);
        Object value = iFieldDecoder.decoder(data);
        return value;
    }



}
